#region usings

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.Drawing.Imaging;


using CStock;
using CUtil;
using CTrading;

using System.Threading;
using CGraph;

using EForms;
using System.Collections.Generic;
#endregion


namespace CapitalReSources
{
	/// <summary>
	/// Summary description for MainClass
	/// </summary>
	public partial class  MainClass : IMainClass
	{

        private void ActivateTabPageAndSetProgramContext(string tabPageName)
        {
            System.Windows.Forms.TabControl tc = this.tabControlStock as System.Windows.Forms.TabControl;
            if (tc.SelectedTab.Name != tabPageName)
            {
                //SelectTabPage(tabPageName);
                SelectTabPageAndSetProgramContext(tabPageName);
            }

        }
      

        private object GetSelection()
        {

            TreeNodeStock node = GetSelectedNode();
            return node.PortfolioOrDataItem;

        }


        #region implementations

        private void ShowFinancialData(IDataItem myDataItem)
        {
            CGrid.GridWindow gridWindow = new CGrid.GridWindow();
            gridWindow.GridBase.CreateGrid(CUtil.GridTypes.TwoColumnGrid, true);


            IDataClass dcd = this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected.DataClass;
            DataClass dc = dcd as DataClass;
            gridWindow.GridBase.AddRow_ForEachProperty(myDataItem.FinancialData);
            gridWindow.ShowDialog();

        }

        private void ChangeCurrentTradeSystem(ITradeSystem ts)
        {
            this.programContext.TradeEconomy.TradeSimulation.TradeSystem = ts;
            string shortFileName = ts.FileName.Remove(ts.FileName.Length - 4, 4);
            this.programContext.TradeEconomy.TradeSystemName = shortFileName;
            this.programContext.TradeEconomy.Serialize_OnlySimpleProperties();


            UpdateViewWithTradeSystem();
        }



        private void UpdateQuotes()
        {
            IDataItem di = null;
            IPortfolio port = this.programContext.TradeEconomy.Portfolio_Selected;

            TreeNode tn = GetSelectedNode();
            if (port.Name == tn.Text)
            {
                //updateWebFinished = false;

                for (int i = 0; i < port.DataItems.Count; i++)
                {
                    IDataItem dit = port.DataItems[i];
                    updateWebFinished = false;

                    this.quoteUpdater.UpdateSingleDataItemQuotes(dit, false);
                    SleepUntilUpdate();
                }
            }

            else
            {
                try
                {
                    di = this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected;
                    this.quoteUpdater.UpdateSingleDataItemQuotes(di, true);
                    return;


                    //this.RefreshTree();
                }
                catch (Exception ex)
                {
                    Debug.Assert(false, "Error getting quotes for: " + di.Name + "; " + ex.Message);
                    return;

                }
            }
        }


        private void SelectTabPageAndSetProgramContext(string tabPageName)
        {

            System.Windows.Forms.TabPage tp = SelectTabPage(tabPageName);

            if (tp != null)
            {
                IContextProvider dp = tp.Controls[0] as IContextProvider;
                if (dp != null)
                {
                    dp.ProgramContext = this.programContext;
                }
                else
                {
                    System.Diagnostics.Debug.Assert(false, "TabPage " + tp.Name + " is not holding stock data ");
                }
            }




        }




        private void FillSelectedIndicatorsListView(IDataItem myDataItem, bool intraday)
        {

            SelectTabPageAndSetProgramContext(ViewsAvailable.dataView.ToString());

            System.Windows.Forms.ListView lV = listViewShareData as System.Windows.Forms.ListView;
            lV.Clear();
            listViewShareData.FillSelectedIndicators(myDataItem, intraday);

        }

        private TreeNodeStock GetSelectedNode()
        {
            System.Windows.Forms.TreeView tv = null;
            if (this.customPortfolioTreeViewActive)
            {
                tv = this.treeViewCustomPortfolios as System.Windows.Forms.TreeView;
            }
            else
            {
                tv = this.treeViewStock as System.Windows.Forms.TreeView;
            }

            //System.Windows.Forms.TreeView tv = this.treeViewStock as System.Windows.Forms.TreeView;
            TreeNodeStock selectedNode = (TreeNodeStock)tv.SelectedNode;
            return selectedNode;

        }
        private IPortfolios GetPortfolios()
        {
            IPortfolios ports = null;
            if (this.customPortfolioTreeViewActive)
            {
                ports = Portfolios_Custom();

            }
            else
            {
                ports = Portfolios_StockMarket();
            }


            return ports;

        }
        private ITreeViewStock GetSelectedTreeView()
        {
            ITreeViewStock treeView = null;
            if (this.customPortfolioTreeViewActive)
            {
                treeView = this.treeViewCustomPortfolios;
            }
            else
            {
                treeView = this.treeViewStock;
            }

            //System.Windows.Forms.TreeView tv = this.treeViewStock as System.Windows.Forms.TreeView;

            return treeView;

        }
        private bool SetSelectedShareOrPortfolio()
        {
            TreeNodeStock selectedNode = GetSelectedNode();

            SelectTabPageAndSetProgramContext(ViewsAvailable.prognosisView.ToString());

            this.tradeControl.ProgramContext = this.programContext;

            switch (selectedNode.TreeNodeBase)
            {
                case TreeNodeInfo.PORTFOLIO:
                    {
                        //this.tradeControl.Portfolio = (Portfolio)this.programContext.TradeEconomy.Portfolio_Selected;		
                        return false;
                    }
                case TreeNodeInfo.SHARE:
                    {
                        DataClass.DeSerialize(this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected.DataClass, this.programContext.Configuration.IntradayModus);
                        return true;

                    }
                default:
                    {

                        //MessageBox.Show("View: Error in menuTradeSystem_Click" + "Wrong or Unknown selected Node Type");
                        return false;
                    }
            }
        }

        #endregion

        #region message receivers


        private bool HandlePortfolioChanged(IPortfolio port, ObjectChangedEventArgs e)
        {
            string propName = e.PropertyName;
            ITreeViewStock selectedTreeView = GetSelectedTreeView();
            if (port != null)
            {
                IDataItem dci = e.Sender as IDataItem;
                port.Serialize();
                switch (propName)
                {
                    case "Number":
                        {
                            port.TradeShares(dci, this.programContext.Configuration.Dates.DateMax, (int)e.OldValue, (int)e.NewValue);


                            break;
                        }
                    case "TransferredMoney":
                        {
                            //port.Serialize(this.programContext.Configuration.Directories.PortfolioPath);
                            break;
                        }
                    case "Name":
                        {
                            //delete old portfolio:

                            selectedTreeView.Refresh();
                            break;
                        }
                    case "ID":
                        {
                            //delete old portfolio:

                            selectedTreeView.Refresh();
                            break;
                        }
                    case "WKN":
                        {
                            selectedTreeView.Refresh();
                            break;
                        }
                    case "Symbol":
                        {
                            selectedTreeView.Refresh();
                            break;
                        }
                    case "Expiry":
                        {
                            port.Serialize();
                            break;
                        }
                    case "IntradayIndicators":
                        {
                            //port.Serialize();
                            break;
                        }
                    case "IntradayIndicatorsIntraday":
                        {
                            //port.Serialize();
                            break;
                        }
                    case "DataItem_Serialize":
                        {
                            //port.Serialize();
                            break;
                        }
                    case "SerializePortfolio":
                        {
                            port.Serialize();
                            break;
                        }

                }
                return true;

            }
            return false;
        }
        private bool HandleDataItemChanged(IDataItem di, ObjectChangedEventArgs e)
        {
            ITreeViewStock selectedTreeView = GetSelectedTreeView();
            string propName = e.PropertyName;
            if (di != null)
            {
                switch (propName)
                {
                    case "Name":
                        {

                            selectedTreeView.Refresh();
                            break;
                        }
                }
                switch (propName)
                {
                    case "Symbol":
                        {

                            selectedTreeView.Refresh();
                            break;
                        }
                }
                switch (propName)
                {
                    case "ToSerialize":
                        {
                            IPortfolio portf = di.Parent as IPortfolio;
                            portf.Serialize();
                            //selectedTreeView();
                            break;
                        }
                }
                switch (propName)
                {
                    case "FundamentalData":
                        {
                            IPortfolio portf = di.Parent as IPortfolio;
                            portf.Serialize();
                            //selectedTreeView();
                            break;
                        }
                }
                return true;
            }
            return false;
        }
        private bool HandleDataFeedHandlerChanged(ObjectChangedEventArgs e)
        {
            string message = e.PropertyName;
            this.view.SetStatusBarText(3, message);

            //this.View.StatusBar.Panels[3].Text = message;
            if (message.Contains("Finished download"))
            {
                updateWebFinished = true;
            }
            else
            {
                updateWebFinished = false;
            }

            return true;


        }

        private bool HandleFundamentalDataDownloadEvent(ObjectChangedEventArgs e)
        {
            string message = e.PropertyName;
            IDataItem di = e.OldValue as IDataItem;
            this.View.StatusBar.Panels[3].Text = message;
            if (message.Contains("Finished"))
            {
                if (gridFundamentalData != null)
                {
                    this.gridFundamentalData.ShowFundamentalData(di.FundamentalData);
                }
            }
            
            return true;

        }
        private bool HandleFinancialDataDownloadEvent(ObjectChangedEventArgs e)
        {
            string message = e.PropertyName;
            IDataItem di = e.OldValue as IDataItem;
            this.View.StatusBar.Panels[3].Text = message;
            if (message.Contains("Finished"))
            {
                di.FinancialData.ObjectChanged -= new ObjectChangedEvent(this.OnObjectChanged);
                //update quote with newest value
                IQuote qu = null;
                if (di.DataClass.QuoteCollection.Count > 0)
                {
                    qu = di.DataClass.QuoteCollection[di.DataClass.QuoteCollection.Count - 1] as IQuote;
                    if (qu.DATE.Day < di.FinancialData.LastQuote.DATE.Day)
                    {
                        di.DataClass.QuoteCollection.Add(di.FinancialData.LastQuote);

                    }
                    else if (qu.DATE.Day == di.FinancialData.LastQuote.DATE.Day)
                    {
                        di.DataClass.QuoteCollection.RemoveAt(di.DataClass.QuoteCollection.Count - 1);
                        di.DataClass.QuoteCollection.Add(di.FinancialData.LastQuote);

                    }


                }
                else
                {
                    qu = di.FinancialData.LastQuote;
                    di.DataClass.QuoteCollection.Add(di.FinancialData.LastQuote);

                }
                di.DataClass.Serialize();

            }
            updateWebFinished = true;
            return true;


        }




        #endregion

        #region indicator selection


        private void ShowIndicatorIntradayCharts()
        {


            IIndicators indColl = this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected.DataClass.IndicatorsIntraday;
            for (int i = 0; i < indColl.Count; i++)
            {
                IIndicator ind = (IIndicator)indColl[i];

                IDataClass myDataClass = this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected.DataClass;

                //Check if the indicator is up to date
                if (ind.Values.Count < this.programContext.TradeEconomy.Portfolio_Selected.DataItem_Selected.DataClass.QuoteCollection.Count)
                {
                    if (myDataClass.QuoteCollection == null)
                    {
                        myDataClass.DeSerialize_IntradayPart();
                    }
                    //ind = IndEvaluator.Indicator_Evaluate(ind);


                }
                else
                {


                }
            }
        }
        #endregion



        #region FundamentalData

        private void ShowPortfolioInStockGrid()
        {
            IGridShowPortfolio gsd = this.gridStockData as IGridShowPortfolio;
            Debug.Assert(gsd != null, "Software error in Tree view - grid type is not correct");


            if (gsd != null)
            {
                gsd.ShowPortfolio(this.programContext.TradeEconomy.Portfolio_Selected);
            }

        }

        private void ShowPortfolioinCustomPortfolioGrid()
        {
            IGridShowPortfolio gsd = this.gridDataView as IGridShowPortfolio;
            Debug.Assert(gsd != null, "Software error in Tree view - grid type is not correct");


            if (gsd != null)
            {
                gsd.ShowPortfolio(this.programContext.TradeEconomy.Portfolio_Selected);
            }

            this.View.Cursor = System.Windows.Forms.Cursors.Default;
        }



        private IPortfolio GetPortfolioWebupdate()
        {
            IPortfolio portf = this.programContext.TradeEconomy.GetPortfolioByID(webupdate_IntradayPortfolioName);
            if (portf == null)
            {
                portf = new Portfolio();
                portf.StockTypePortfolio = false;
                portf.ID = webupdate_IntradayPortfolioName;
                portf.OwnerID = this.programContext.TradeEconomy.ID;
                portf.Serialize();
            }
            return portf;


        }


        private void GetIntradayQuotesAndOnlySaveThem()
        {

            for (int i = 0; i < this.programContext.TradeEconomy.Portfolios.Items.Count; i++)
            {
                IPortfolio port = this.programContext.TradeEconomy.Portfolios[i] as IPortfolio;
                if (port.FetchIntradayQuotes)
                {

                    for (int j = 0; j < port.DataItems.Count; j++)
                    {
                        IDataItem di = port.DataItems[i];
                        this.yahooIntraday.AddShareToList(di);
                    }
                }
            }
            this.yahooIntraday.StartDownload();

            //this.View.Cursor = System.Windows.Forms.Cursors.Default;


        }

        private void GetLastIntradayQuotes()
        {
            for (int i = 0; i < this.programContext.TradeEconomy.Portfolios.Items.Count; i++)
            {
                IPortfolio port = this.programContext.TradeEconomy.Portfolios[i] as IPortfolio;
                GetPortfolioIntradayQuotes(port);
            }


        }
    
        private void GetShareIntradayQuotes(IDataItem dit)
        {

            dit.FinancialData.ObjectChanged += new ObjectChangedEvent(this.OnObjectChanged);
            updateWebFinished = false;
            dit.FinancialData.UpdateFromWeb(false);

            //replace the last quote of the dataItem
            dit.DataClass.UpdateLastQuote(dit.FinancialData.LastQuote);

            SleepUntilUpdate();

        }

        private void UpdatePortfolioIntradayAndShowInGrid()
        {
            IPortfolio port = this.programContext.TradeEconomy.Portfolio_Selected;
            port.FetchIntradayQuotes = true;

            GetPortfolioIntradayQuotes(port);
            ShowPortfolioInStockGrid();
            port.Serialize();


        }

        
        private void UpdateFundamentalData_Years(IDataItem di)
        {

            WebFundamentalData fd = new WebFundamentalData();
            fd.GetFundamentalData_Years(di, this.programContext.Configuration.Dates.DateMinWebupdate, false);

            //di.Serialize_WithoutDataClass();
            IPortfolio portf = di.Parent as IPortfolio;
            portf.Serialize();

            //di.Serialize();
            if (gridFundamentalData != null)
            {
                this.gridFundamentalData.ShowFundamentalData(di.FundamentalData);
            }

        }
        private void UpdateFundamentalData_Quartal(IDataItem di)
        {
            di.ObjectChanged += new ObjectChangedEvent(this.OnObjectChanged);
            
            WebFundamentalData fd = new WebFundamentalData();
            fd.GetFundamentalData_Quartal(di, true);
            
            //di.Serialize_WithoutDataClass();
            IPortfolio portf = di.Parent as IPortfolio;
            //portf.Serialize();

            //di.Serialize();
            //have to do this asynchronously
          

        }
      
        
        private void UpdateFundamentalData_Years(IPortfolio port)
        {
            for (int i = 0; i < port.DataItems.Count; i++)
            {
                IDataItem di = port.DataItems[i];
                UpdateFundamentalData_Years(di);

            }
            port.Serialize();

        }

        private void UpdateFundamentalData_Quartal(IPortfolio port)
        {
            for (int i = 0; i < port.DataItems.Count; i++)
            {
                IDataItem di = port.DataItems[i];
                UpdateFundamentalData_Quartal(di);

            }
            port.Serialize();

        }
        #endregion

        private void DownloadUpateFile()
        {


            WebClientFeed.DownloadFile("http://", @"C:\tmp\1.txt");


        }
        private void OnClosedChartWindow(object sender, System.EventArgs e)
        {

            CGraph.ChartWindow chartIntraday = sender as CGraph.ChartWindow;
            chartIntraday.Closed -= new System.EventHandler(this.OnClosedChartWindow);

            //try both...
            chartWindows.Remove(chartIntraday);
            chartWindowsShare.Remove(chartIntraday);


        }
        private bool ReturnIfChartWindowExists(IDataItem di)
        {
            for (int i = 0; i < chartWindows.Count; i++)
            {
                CGraph.ChartWindow chartWindow = chartWindows[i] as CGraph.ChartWindow;
                if (chartWindow.DataItem.DataClass.ID == di.DataClass.ID)
                {
                    return true;
                }
            }
            return false;
        }
        private void Initialize_ChartData_AndShow(IDataItem di)
        {
            try
            {
                this.programContext.Logfile.WriteTimeSpanLog("       -show chart from MainWindow");

                CGraph.ChartWindow chartWindow = new CGraph.ChartWindow();

                if (chartWindow.Initialize_ChartData(this.programContext, di))
                {
                    this.chartWindows.Add(chartWindow);
                    chartWindow.Closed += new System.EventHandler(this.OnClosedChartWindow);


                    //di.DataClass.DeSerialize();
                    //chartWindow.Plot(false);
                    chartWindow.Show();
                }
                else
                {
                    // do not show - no data there
                }
            }
            catch (Exception ex)
            {
                Debug.Assert(false, "SW Error - init chart data " + ex.Message);
            }

        }
        private void UpdateFinancialData()
        {
            //IDataItem di = null;
            IPortfolio port = this.programContext.TradeEconomy.Portfolio_Selected;
            ITreeViewStock selectedTreeView = GetSelectedTreeView();
            TreeNode tn = GetSelectedNode();


            if (port.Name == tn.Text)
            {
                UpdateFinancialData(port);
                ShowPortfolioInStockGrid();
            }
            else
            {
                IDataItem di = port.DataItem_Selected;
                UpdateFinancialData(di);

            }

            return;

        }
        private void UpdateFundamentalData_Years()
        {

            IPortfolio port = this.programContext.TradeEconomy.Portfolio_Selected;
            ITreeViewStock selectedTreeView = GetSelectedTreeView();
            TreeNode tn = GetSelectedNode();


            if (port.Name == tn.Text)
            {
                UpdateFundamentalData_Years(port);
                ShowPortfolioInStockGrid();
            }
            else
            {
                IDataItem di = port.DataItem_Selected;
                UpdateFundamentalData_Years(di);

            }

            return;

        }
          private void UpdateFundamentalData_Quartal()
        {

            IPortfolio port = this.programContext.TradeEconomy.Portfolio_Selected;
            ITreeViewStock selectedTreeView = GetSelectedTreeView();
            TreeNode tn = GetSelectedNode();


            if (port.Name == tn.Text)
            {
                UpdateFundamentalData_Quartal(port);
                ShowPortfolioInStockGrid();
            }
            else
            {
                IDataItem di = port.DataItem_Selected;
                UpdateFundamentalData_Quartal(di);

            }

            return;

        }
        

        private void SleepUntilUpdate()
        {

            for (int i = 0; i < 100; i++)
            {
                System.Threading.Thread.Sleep(10);
                if (updateWebFinished)
                    break;

            }
        }

        private void ChartShareWindow(IDataItem di)
        {
            try
            {
                this.View.Cursor = System.Windows.Forms.Cursors.WaitCursor;
                this.programContext.Configuration.IntradayModus = false;
                //1. see if already there

                for (int i = 0; i < chartWindowsShare.Count; i++)
                {
                    CGraph.ChartWindow chartWindow = chartWindowsShare[i] as CGraph.ChartWindow;
                    if (chartWindow.DataItem != null && chartWindow.DataItem.DataClass.ID == di.DataClass.ID)
                    {
                        this.View.Cursor = System.Windows.Forms.Cursors.Default;
                        return;
                    }
                }
                //2. create new
                try
                {
                    CGraph.ChartWindow chartWindow = new CGraph.ChartWindow();
                    if (chartWindow.Initialize_ChartData(this.programContext, di))
                    {
                        chartWindow.Closed += new System.EventHandler(this.OnClosedChartWindow);
                        //chartWindow.Closed += new EventHandler(
                        this.chartWindowsShare.Add(chartWindow);
                        //chartWindow.Charts[0].DataItem = di;
                        //chartWindow.Charts[0].Plot_Share(false);
                        chartWindow.Show();
                    }
                    else
                    {
                        ChartDataNotAvailable(di);

                    }



                }

                catch (Exception exc)
                {
                    System.Diagnostics.Debug.Assert(false, "Error updating chart intraday for " + di.Name, exc.Message);
                }

                this.View.Cursor = System.Windows.Forms.Cursors.Default;

            }
            catch (Exception exMain)
            {
                System.Diagnostics.Debug.Assert(false, "Error updating chart intraday for " + di.Name, exMain.Message);

            }


        }


        private void UpdateFinancialData(IDataItem di)
        {
            di.FinancialData.ObjectChanged += new ObjectChangedEvent(this.OnObjectChanged);
            di.FinancialData.UpdateFromWeb(true);

        }


        private void UpdateFinancialData(IPortfolio port)
        {
            for (int i = 0; i < port.DataItems.Count; i++)
            {
                IDataItem dit = port.DataItems[i];
                GetShareIntradayQuotes(dit);

            }
            port.Serialize();

        }
        
	}
}
